#! /usr/bin/env python
# -*- coding: utf8 -*-

import pygtk
pygtk.require("2.0")
import gtk
import sys

if sys.version_info[:2] == (2, 5):
    from xml.etree import ElementTree as et
else:
    from elementtree import ElementTree as et

class algorithm(object):
    """
    This class parses a node containing an algorithm's meta-data, and provides
    the interface to configure it.c
    """
    
    def __init__(self, node):
        self.__node = node

        self.__name        = node.find("name").text
        self.__pretty_name = node.find("pretty_name").text
        
        if node.find("description"):
            self.__description = node.find("description").text
        
        self.__containers = []
        
        self.__entries        = {}
        self.__list_entries   = {}
        self.__toggles        = {}
        self.__list_ele_names = {}
        
        map(self.__conf_field, node.findall("./fields/field"))
        
    def __conf_field(self, node):
        name = node.find("name").text
        
        if node.find("type").text != "toggle":
            container = gtk.HBox()
            self.__containers.append(container)    
            container.pack_start(gtk.Label(node.find("pretty_name").text + ":"), False, False, 5)
            
        if node.find("type").text == "list":
            self.__list_entries[name] = gtk.TextView()
            scroll                    = gtk.ScrolledWindow()
            
            scroll.add(self.__list_entries[name])
            container.pack_start(scroll, padding=5)
            self.__list_ele_names[name] = node.find("element_name").text
        elif node.find("type").text == "text":
            self.__entries[name] = gtk.Entry()
            container.pack_start(self.__entries[name], padding=5)
        elif node.find("type").text == "toggle":
            self.__toggles[name] = gtk.CheckButton(node.find("pretty_name").text)
            self.__containers.append(self.__toggles[name])
        
        [x.show_all() for x in self.__containers]           

    # Public methods
    def append_elements(self, parent):
        for i in self.__containers:
            parent.pack_start(i, padding=5)
            parent.reorder_child(i, len(parent) - 2)
            
    def remove_elements(self):
        [x.parent.remove(x) for x in self.__containers if x.parent != None]
        [x.get_buffer().set_text("") for x in self.__list_entries.values()]
        [x.set_text("") for x in self.__entries.values()]
        [x.set_active(False) for x in self.__toggles.values()]
        
    def open_state(self, node):
        for tag, entry in self.__entries.items():
            n = node.find("./parameters/%s" % (tag,))
            
            if n != None:
                entry.set_text(n.text)
        
        for tag, toggle in self.__toggles.items():
            n = node.find("./parameters/%s" % (tag,))
            
            if n != None:
                toggle.set_active(n.text == "True")
                
        for tag, text_view in self.__list_entries.items():
            values = [x.text for x in node.findall("./parameters/%s/%s" % (tag, self.__list_ele_names[tag]))]
            text_view.get_buffer().set_text("\n".join(values))
            
        
    def xml(self, name):
        """Returns the xml file for the current entries"""
        node = et.Element("algorithm")
        base = et.Element("base")
        
        nnode = et.Element("name")
        nnode.text = name
        node.append(nnode)
        
        
        base.text = self.__name
        node.append(base)
        
        params = et.Element("parameters")
        node.append(params)
        
        for tag, entry in self.__entries.items():
            n = et.Element(tag)
            n.text = entry.get_text().strip()
            params.append(n)

        for tag, list_view in self.__list_entries.items():
            buff = list_view.get_buffer()
            n = et.Element(tag)
            params.append(n)
            
            tmp = buff.get_text(buff.get_start_iter(), buff.get_end_iter())
            for i in [x.strip() for x in tmp.split("\n") if x.strip() != ""]:
                e = et.Element(self.__list_ele_names[tag])
                e.text = i
                n.append(e)
                
        for tag, toggle in self.__toggles.items():
            n = et.Element(tag)
            params.append(n)
            n.text = "%s" % (toggle.get_active(),)
                
        return node
        
    # Properties
    @property
    def name(self):
        return self.__name
        
    @property
    def pretty_name(self):
        return self.__pretty_name
